#include "Duck.h"
#include <GL/freeglut.h>
#include <math.h>

	GLfloat velocity[3];
	GLfloat location[3];
	bool inMotion;

	GLuint display_list_handle;
	GLuint duck_as_life_handle;

	/*
		Creates the torso of the duck complete with wings
	*/
	void Duck::DuckBody(void)
	{
		//	Joint creates a sphere of radius 0.5 located at the current frame's origin.
		glClearColor(1,1,1,0);
		glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 128.0f);
		glPushMatrix();
		glColor4f(1.0,1.0,0.0,1.0);
		glScalef(.9f, .6f, .8f);
		glutSolidSphere(0.5 , 30 , 30);
		glPopMatrix();

		//right wing
		glPushMatrix();
		glTranslated(0,0,.4);
		glScalef(1.1f, .4f, .6f);
		glutSolidSphere(.2, 30, 15);
		glPopMatrix();

		//left wing
		glPushMatrix();
		glTranslated(0,0,-.4);
		glScalef(1.1f, .4f, -.6f);
		glutSolidSphere(.2, 15, 15);
		glPopMatrix();
	}

	/*
		Creates the Head of the duck.
	*/
	void Duck::DuckHead(void)
	{
		glClearColor(1.0,1.0,1.0,0.0);
		glPushMatrix();
		glColor4f(1,1,0,1);
		glutSolidSphere(0.2 , 30 , 30);
		glPopMatrix();
	}
	/*
		Draws the facial features of the duck. These include a beak with two lines down the middle to resemble a mouth, and two eyes
	*/
	void Duck::DuckFace(void)
	{
		//draws the beak
		glClearColor(1.0,1.0,1.0,0.0);
		glPushMatrix();
		glColor4f(1.0,0.5,0.0,1.0);
		glTranslated(0.02, 0.0,-0.02);
		glutSolidCone(.06, 0.1, 20, 10);

		glColor3f(0.0,0.0,0.0);

		//one side of mouth
		glBegin(GL_LINES);
		glVertex3d(0.06,0,0.0);
		glVertex3d(0.0,0.0,.1);
		glEnd();

		//other side of mouth
		glBegin(GL_LINES);
		glVertex3d(-0.06,0,0.0);
		glVertex3d(0,0,.1);
		glEnd();
		glPopMatrix();
		glColor4f(0,0,0,0);

		//left eye
		glPushMatrix();
		glTranslated(.1,.12, -.1);
		glutSolidSphere(.03, 5, 5);
		glPopMatrix();

		//right eye
		glTranslated(-.1,.12,-.1);
		glutSolidSphere(.03, 5, 5);
	}

	/*
		Sets whether the duck is currently in motion (has he been shot?)
	*/
	void Duck::setDuckShot(bool duckShot)
	{
		inMotion = duckShot;
	}

	/*
		Sets the location coordinates of the duck
	*/
	void Duck::SetDuckLocation(double x, double y, double z)
	{
		xLocation = x;
		yLocation = y;
		zLocation = z;
	}

	/*
		Sets the duck's rotation values (stemming from the gun's rotation)
	*/
	void Duck::RotateDuck(double x, double y, double z)
	{
		if(!inMotion)
		{
			xRotation = x;
			yRotation = y;
			zRotation = z;
		}
	}

	/*
		After a collision with a balloon the duck loses it's composure and spins out of control
	*/
	void Duck::SpinDuck(double time)
	{
		ySpin += time * 360;
		if(ySpin >= 360)
			ySpin = ySpin - 360;
	}

	/*
		This display method for the duck is called when a projectile duck must be displayed. This method pieces together the parts
		and uses a display list after the first display.
	*/
	void Duck::DisplayDuck(void)
	{
		glPushMatrix();

		//Global positioning
		glTranslated(xLocation, yLocation, zLocation);
		glTranslatef(0, 0, -6);
		glTranslated(0, -1, 0);
		//go 2 units forward, then rotate then go 2 units back to end of gun (draws the duck perfectly on the gun)
		glTranslated(0, 0, 2);
		glRotated(yRotation, 0, 1, 0);
		glRotated(xRotation, 1, 0, 0);
		glTranslated(0, 1, 2);

		if(display_list_handle == (GLuint)-1){
			display_list_handle = glGenLists(1);
			glNewList(display_list_handle, GL_COMPILE);

		//Local positioning
		glRotated(90, 0, 1, 0);
		DuckBody();
		glTranslated(.4, .2, 0);
		DuckHead();
		glTranslated(.2, 0, 0);
		glRotatef(90.0f, 0, 1.0f ,0);
		DuckFace();
		glEndList();
		
		}
		glCallList(display_list_handle);
		glPopMatrix();
	}

	/*
		This display method is used for when a duck life is needed to be displayed on screen. This method should be called when
		the projection is orthographic in order to achieve a hud-like experience. This method is also the one used by the beauty mode
		because it does no global positioning beforehand.
	*/
	void Duck::DisplayDuckAsLife(double window_width, double window_height){
		glPushMatrix();

		if(duck_as_life_handle == (GLuint)-1){
			duck_as_life_handle = glGenLists(1);
			glNewList(duck_as_life_handle, GL_COMPILE);
		
		//Local positioning
		DuckBody();
		glTranslatef(.4f, .2f, 0.0f);
		DuckHead();
		glTranslatef(.2f, 0.0f, 0.0f);
		glRotatef(90.0f, 0, 1.0f ,0);
		DuckFace();
		glEndList();		
		}
		glCallList(duck_as_life_handle);

		glPopMatrix();
	}

	/*
		Constructs a new duck and initializes necessarry components
	*/
	Duck::Duck(void)
	{
		duck_as_life_handle = -1;
		display_list_handle = -1;
		xLocation = 0;
		yLocation = 0;
		zLocation = 0;
		xRotation = 0;
		yRotation = 0;
		zRotation = 0;
		ySpin = 0;
	}
	/*
		gets the current x location of the duck
	*/
	double Duck::getXLocation(void){
		return xLocation;
	}

	/*
		gets the current y location of the duck
	*/
	double Duck::getYLocation(void){
		return yLocation;
	}

	/*
		gets the current z location of the duck
	*/
	double Duck::getZLocation(void){
		return zLocation;
	}

	/*
		determines the x coordinate of a collision (if it were to occur).
	*/
	double Duck::getCollisionXLocation(void){
		return xLocation + (2*sin(2 * 3.1416 * yRotation / 360));
	}

	/*
		determines the y coordinate of a collision (if it were to occur).
	*/
	double Duck::getCollisionYLocation(void){
		return yLocation - (2*sin(2 * 3.1416 * xRotation / 360));
	}

	/*
		determines the z coordinate of a collision (if it were to occur).
	*/
	double Duck::getCollisionZLocation(void){
		return zLocation;
	}
